package com.company.cloud.work.modules.app.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.auth.annotation.Authc;
import com.company.cloud.common.auth.annotation.Login;
import com.company.cloud.common.bean.BaseClientResult;
import com.company.cloud.common.bean.BaseResult;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.constant.BaseConstant;
import com.company.cloud.common.constant.BaseReturnEnum;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.common.utils.AuthContextUtils;
import com.company.cloud.common.utils.CheckUtils;
import com.company.cloud.common.utils.StrSplitUtils;
import com.company.cloud.user.modules.api.response.UserSimple;
import com.company.cloud.user.modules.api.service.UserRemoteService;
import com.company.cloud.work.modules.base.entity.TaskExeInfo;
import com.company.cloud.work.modules.base.entity.TaskInfo;
import com.company.cloud.work.modules.base.service.TaskExeInfoService;
import com.company.cloud.work.modules.base.service.TaskInfoService;
import com.company.cloud.work.modules.cache.models.WorkTaskExe;
import com.company.cloud.work.modules.cache.models.WorkTaskExeModel;
import com.company.cloud.work.modules.cache.models.WorkTaskModel;
import com.company.cloud.work.modules.cache.utils.CrmWorkChangeUtils;
import com.company.cloud.work.modules.mgr.controller.req.*;
import com.company.cloud.work.modules.mgr.service.WorkReceiptMgrService;
import com.company.cloud.work.modules.mgr.service.WorkTaskMgrService;
import com.company.common.server.constant.IRelBusiType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;

@Login
@RestController
@RequestMapping("/app/crm/workTask")
@Api(tags="CRM_APP_工作任务")
public class WorkTaskAppController {

    @Autowired
    private TaskInfoService taskInfoService;
    @Autowired
    private TaskExeInfoService taskExeInfoService;
    @Autowired
    private UserRemoteService userRemoteService;
    @Autowired
    private WorkReceiptMgrService workReceiptMgrService;
    @Autowired
    private WorkTaskMgrService workTaskMgrService;

    @PostMapping("/queryByUser")
    @ApiOperation(value="查询我创建的任务", response= WorkTaskModel.class)
    public BaseResult queryByUser(@RequestBody WorkTaskByUserQuery4PageParam params) {
        ValidatorUtils.validate(params);
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        String runUserId=null;
        if(CheckUtils.hasInt(params.getRunUserId())) {
            runUserId= StrUtil.format(",{},", params.getRunUserId());
        }
        IPage<TaskInfo> page =  taskInfoService.page(
                new Page<>(params.getPage(), params.getRows()),
                new QueryWrapper<TaskInfo>()
                        .eq("user_id",userInfo.getId())
                        .eq("rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
                        .eq(StringUtils.hasText(params.getState()), "state", params.getState())
                        .eq(StringUtils.hasText(params.getTitle()), "title", params.getTitle())
                        .like(StringUtils.hasText(runUserId), "run_user_ids", runUserId)
        );

        if (page == null || CollectionUtils.isEmpty(page.getRecords())) {
            return BaseResult.ok();
        }
        Set<Integer> userIds=new HashSet<Integer>();
        page.getRecords().forEach(item->{
            if(CheckUtils.hasInt(item.getUserId())) {
                userIds.add(item.getUserId());
            }
            userIds.addAll(StrSplitUtils.parse2list(item.getRunUserIds(), Integer.class));
        });
        BaseClientResult<Map<Integer, UserSimple>> userMap2=userRemoteService.getUserMapByIds(userIds);
        Map<Integer, UserSimple> userMap;
        if(CheckUtils.hasClientResult(userMap2)){
            userMap=userMap2.getData();
        }else{
            userMap=new HashMap<>();
        }

        IPage<WorkTaskModel> data=page.convert(new Function<TaskInfo, WorkTaskModel>() {
            @Override
            public WorkTaskModel apply(TaskInfo entity) {


                WorkTaskModel workTaskModel = CrmWorkChangeUtils.getWorkTaskModel(entity,userMap);
                List<TaskExeInfo> taskExeList = taskExeInfoService.list(new QueryWrapper<TaskExeInfo>()
                        .eq("task_id", entity.getId())
                );
                if(!CollectionUtils.isEmpty(taskExeList)) {
                    List<WorkTaskExe> taskExe = new ArrayList<>();
                    taskExeList.forEach(exe->{
                        taskExe.add(CrmWorkChangeUtils.getWorkTaskExe(exe, userMap));
                    });
                    workTaskModel.setTaskExe(taskExe);
                }
                return  workTaskModel;
            }
        }) ;

        return BaseResult.ok(data);
    }


    @PostMapping("/queryByRunUser")
    @ApiOperation(value="查询分配给我的任务", response= WorkTaskExeModel.class)
    public BaseResult queryByRunUser(@RequestBody WorkTaskByRunUserQuery4PageParam params) {
        ValidatorUtils.validate(params);
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        IPage<TaskExeInfo> page =  taskExeInfoService.page(
                new Page<>(params.getPage(), params.getRows()),
                new QueryWrapper<TaskExeInfo>()
                        .eq("exe_user_id", userInfo.getId())
                        .eq(StringUtils.hasText(params.getState()), "exe_state", params.getState())
                        .orderByDesc("exe_date")
        );

        if (page == null || CollectionUtils.isEmpty(page.getRecords())) {
            return BaseResult.ok();
        }

        Set<Integer> taskIds=new HashSet<Integer>();
        page.getRecords().forEach(item->{
            if(CheckUtils.hasInt(item.getTaskId())) {
                taskIds.add(item.getTaskId());
            }
        });
        List<TaskInfo> taskInfoList= taskInfoService.listByIds(taskIds);
        Map<Integer,TaskInfo> taskInfoMap = new HashMap<>();
        Set<Integer> userIds=new HashSet<Integer>();
        if(!CollectionUtils.isEmpty(taskInfoList)){
            taskInfoList.forEach(item->{
                taskInfoMap.put(item.getId(),item);
                userIds.add(item.getUserId());
            });
        }

        BaseClientResult<Map<Integer, UserSimple>> userMap2=userRemoteService.getUserMapByIds(userIds);
        Map<Integer, UserSimple> userMap;
        if(CheckUtils.hasClientResult(userMap2)){
            userMap=userMap2.getData();
        }else{
            userMap=new HashMap<>();
        }

        IPage<WorkTaskExeModel> data=page.convert(new Function<TaskExeInfo, WorkTaskExeModel>() {
            @Override
            public WorkTaskExeModel apply(TaskExeInfo entity) {
                return  CrmWorkChangeUtils.getWorkTaskExeModel2(entity,taskInfoMap,userMap);
            }
        }) ;

        return BaseResult.ok(data);
    }




    @PostMapping("/query")
    @ApiOperation(value="查询", response=WorkTaskModel.class)
    public BaseResult query(@RequestBody WorkTaskQuery4PageParam params) {
        ValidatorUtils.validate(params);
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        String runUserId=null;
        if(CheckUtils.hasInt(params.getRunUserId())) {
            runUserId=StrUtil.format(",{},", params.getRunUserId());
        }
        IPage<TaskInfo> page =  taskInfoService.page(
                new Page<>(params.getPage(), params.getRows()),
                new QueryWrapper<TaskInfo>()
                        .eq("company_no", userInfo.getCompanyNo())
                        .eq("rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
                        .eq(StringUtils.hasText(params.getState()), "state", params.getState())
                        .eq(StringUtils.hasText(params.getTitle()), "title", params.getTitle())
                        .eq(CheckUtils.hasInt(params.getUserId()), "user_id", params.getUserId())
                        .like(StringUtils.hasText(runUserId), "run_user_ids", runUserId)
        );


        if (page == null || CollectionUtils.isEmpty(page.getRecords())) {
            return BaseResult.ok();
        }
        Set<Integer> userIds=new HashSet<Integer>();
        page.getRecords().forEach(item->{
            if(CheckUtils.hasInt(item.getUserId())) {
                userIds.add(item.getUserId());
            }
            userIds.addAll(StrSplitUtils.parse2list(item.getRunUserIds(), Integer.class));
        });

        BaseClientResult<Map<Integer, UserSimple>> userMap2=userRemoteService.getUserMapByIds(userIds);
        Map<Integer, UserSimple> userMap;
        if(CheckUtils.hasClientResult(userMap2)){
            userMap=userMap2.getData();
        }else{
            userMap=new HashMap<>();
        }

        IPage<WorkTaskModel> data=page.convert(new Function<TaskInfo, WorkTaskModel>() {
            @Override
            public WorkTaskModel apply(TaskInfo entity) {
                WorkTaskModel workTaskModel = CrmWorkChangeUtils.getWorkTaskModel(entity,userMap);
                List<TaskExeInfo> taskExeList = taskExeInfoService.list(new QueryWrapper<TaskExeInfo>()
                        .eq("task_id", entity.getId())
                );
                if(!CollectionUtils.isEmpty(taskExeList)) {
                    List<WorkTaskExe> taskExe = new ArrayList<>();
                    taskExeList.forEach(exe->{
                        taskExe.add(CrmWorkChangeUtils.getWorkTaskExe(exe, userMap));
                    });
                    workTaskModel.setTaskExe(taskExe);
                }
                return workTaskModel;
            }
        }) ;

        return BaseResult.ok(data);
    }

    @PostMapping("/add")
    @ApiOperation(value="新增", response=BaseResult.class)
    public BaseResult add(@RequestBody WorkTaskSaveParam params) {
        ValidatorUtils.validate(params);
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        if(CollectionUtils.isEmpty(params.getRunUserIds())){
            Set<Integer> runUserIds=new HashSet<>();
            runUserIds.add(userInfo.getId());
            params.setRunUserIds(runUserIds);
        }
        workTaskMgrService.add(params,userInfo);
        return BaseResult.ok();
    }


    @PostMapping("/edit")
    @ApiOperation(value="修改", response=BaseResult.class)
    public BaseResult edit(@RequestBody WorkTaskUpdateParam params) {
        ValidatorUtils.validate(params);
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        workTaskMgrService.update(params,userInfo);
        return BaseResult.ok();
    }

    @GetMapping("/get")
    @ApiOperation(value="获取", response=WorkTaskModel.class)
    public BaseResult get(@RequestParam("id")Integer id) {
        TaskInfo entity=taskInfoService.getById(id);
        if (entity == null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())) {
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();

        Set<Integer> userIds=new HashSet<Integer>();
        userIds.add(entity.getUserId());
        userIds.addAll(StrSplitUtils.parse2list(entity.getRunUserIds(), Integer.class));
        BaseClientResult<Map<Integer, UserSimple>> userMapResult=userRemoteService.getUserMapByIds(userIds);
        Map<Integer, UserSimple> userMap= BaseClientResult.getResultData(userMapResult,new HashMap<Integer, UserSimple>());

        WorkTaskModel data= CrmWorkChangeUtils.getWorkTaskModel(entity,userMap);
        if(BaseConstant.YNEnum.YES.getCode().equals(entity.getIsReceipt())) {
            workReceiptMgrService.save(IRelBusiType.CRM_WorkTask_ID, entity.getId().toString(), null, userInfo);
        }
        List<TaskExeInfo> taskExeList = taskExeInfoService.list(new QueryWrapper<TaskExeInfo>()
                .eq("task_id", entity.getId())
        );
        if(!CollectionUtils.isEmpty(taskExeList)) {
            List<WorkTaskExe> taskExe = new ArrayList<>();
            taskExeList.forEach(exe->{
                taskExe.add(CrmWorkChangeUtils.getWorkTaskExe(exe, userMap));
            });
            data.setTaskExe(taskExe);
        }
        return BaseResult.ok(data);
    }


    @GetMapping("/remove")
    @ApiOperation(value="删除", response=BaseResult.class)
    public BaseResult remove(@RequestParam("id")Integer id) {
        TaskInfo entity=taskInfoService.getById(id);
        if (entity == null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())) {
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        entity.setRowsState(BaseConstant.EnabledEnum.DISABLED.getCode());
        entity.addEditParam(userInfo);
        taskInfoService.updateById(entity);
        return BaseResult.ok();
    }



    @PostMapping("/exe")
    @ApiOperation(value="执行", response=BaseResult.class)
    public BaseResult exe(@RequestBody WorkTaskExeParam params) {
        ValidatorUtils.validate(params);
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        workTaskMgrService.exe(params,userInfo);
        return BaseResult.ok();
    }


    @PostMapping("/exeList")
    @ApiOperation(value="执行列表", response=WorkTaskExeModel.class)
    public BaseResult exeList(@RequestBody WorkTaskExeListParam params){
        ValidatorUtils.validate(params);
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        List<TaskExeInfo> teList=taskExeInfoService.list(new QueryWrapper<TaskExeInfo>()
                .eq("company_no", userInfo.getCompanyNo())
                .eq(CheckUtils.hasInt(params.getTaskId()), "task_id", params.getTaskId())
                .eq(CheckUtils.hasInt(params.getExeUserId()), "exe_user_id", params.getExeUserId())
                .eq(CheckUtils.hasInt(params.getExeCommentUserId()), "exe_comment_user_id", params.getExeCommentUserId())
        );
        List<WorkTaskExeModel> result=new ArrayList<WorkTaskExeModel>();



        if(!CollectionUtils.isEmpty(teList)) {
            Set<Integer> userIds=new HashSet<Integer>();
            teList.forEach(item->{
                userIds.add(item.getExeUserId());
                userIds.add(item.getExeCommentUserId());
            });
            BaseClientResult<Map<Integer, UserSimple>> userMapResult=userRemoteService.getUserMapByIds(userIds);
            Map<Integer, UserSimple>  userMap=BaseClientResult.getResultData(userMapResult,new HashMap<Integer, UserSimple>());
            teList.forEach(item->{
                result.add(CrmWorkChangeUtils.getWorkTaskExeModel(item,userMap));
            });
        }
        return BaseResult.ok(result);
    }

    @PostMapping("/exeComment")
    @ApiOperation(value="点评", response=BaseResult.class)
    public BaseResult exeComment(@RequestBody WorkTaskExeCommentParam params) {
        ValidatorUtils.validate(params);
        TaskExeInfo entity=taskExeInfoService.getById(params.getId());
        if (entity == null) {
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        LoginSimpleUserInfo userInfo= AuthContextUtils.getUser();
        entity.setExeComment(params.getExeComment());
        entity.setExeCommentDate(LocalDateTime.now());
        entity.setExeCommentUserId(userInfo.getId());
        entity.addEditParam(userInfo);
        taskExeInfoService.updateById(entity);
        return BaseResult.ok();
    }

}
